import { Injectable, EventEmitter } from "@angular/core";
import { INTERACTIVE_PROP } from "./interactive.directive";

type Listeners = {
  eventName: string;
  listeners: Listener[]
};

type Listener = {
  key: string | symbol;
  emitter: EventEmitter<Event>;
};

@Injectable()
export class InteractiveService {
  currentActiveId: symbol;
  eventStore: Listeners[] = [];

  constructor() {
    document.addEventListener("click", e => {
      if (!e["path"]) {
        return e.target["isInteractiveItem"] ? null : this.currentActiveId = undefined;
      }
      (<any[]>e["path"]).filter((ele: HTMLElement) => ele["isInteractiveItem"]).length ? null : this.currentActiveId = undefined;
    });
  }

  registerMember(key: string | symbol, eventEmitter: EventEmitter<Event>, eventName: string) {
    // console.debug("Register Interactive: ", key, eventEmitter, eventName);
    this.eventStore = this.addListener(this.eventStore, key, eventEmitter, eventName);
  }

  unregisterMember(key: string | symbol) {
    this.eventStore = this.removeListener(this.eventStore, key);
  }

  addListener(store: Listeners[], key: string | symbol, emitter: EventEmitter<Event>, eventName: string): Listeners[] {
    if (store.filter(listeners => listeners.eventName === eventName).length === 0) {
      document.addEventListener(eventName, this.dispatcher.bind(this));
      return [...store, {
        eventName,
        listeners: [{
          key,
          emitter
        }]
      }];
    }
    return store.map(listeners =>
      listeners.eventName === eventName ?
        Object.assign({}, listeners, { listeners: [...listeners.listeners, { key, emitter }] }) :
        listeners
    );
  }

  setFocusActive(id) {
    this.currentActiveId = id;
  }

  getFocusedActive() {
    return this.currentActiveId;
  }

  removeListener(store: Listeners[], key: string | symbol) {
    return store.map(event => Object.assign({}, event, {
      listener: event.listeners.filter(listener => listener.key === key)
    }));
  }

  dispatcher(e: Event) {
    let suitableList = this.eventStore.filter(events => events.eventName === e.type);

    // console.debug("dispatcher: ", this.eventStore, suitableList);
    if (suitableList.length === 0) {
      return;
    }
    let suitable = suitableList[0];
    // console.debug("dispatcher: ", this.eventStore, suitable, e.type);
    suitable.listeners.forEach(member => member.emitter.next(e));
  }



}